package dk.au.cs.peterbn.annotations;

import spoon.reflect.declaration.CtAnnotation;

import java.lang.annotation.*;

/**
 * Annotation for types that play a role in a designpattern.
 */
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
public @interface Pattern {

    public enum Fields implements PropertyIdentifier{
        NAME("name"),
        ID("id"),
        ROLE("role"),
        OVERRIDE_TARGET("overrideTarget"),
        OMIT_IMPLEMENTATION("omitImplementation"),;
        private final String s;

        Fields(String s) {
            this.s = s;
        }

        @Override
        public String propName() {
            return s;
        }

        public static String val(Fields field, CtAnnotation<Pattern> annotation) {
            return annotation.getElementValue(field.propName()).toString();
        }
    }

    /**
     * The name of the pattern. This should be on the form group:name[/variation] where
     * <ul>
     *     <li>group is the group identifier, such as gof for Gang of Four: Design Patterns</li>
     *     <li>name is the canonical name for the pattern in that group, such as Observer</li>
     *     <li>variation is the name of a variation of the pattern, such as Event</li>
     * </ul>
     * @return Pattern identifier
     */
    public String name();

    /**
     * The system wide identifier for this pattern instance.
     * @return Pattern instance identifier
     */
    public String id();

    /**
     * The role the annotated type plays in the given pattern instance
     * @return The annotee's role in the pattern.
     */
    public String role();

    /**
     * Override the target property for this particular annotation.
     * @return The rationale for the target property of the role being overridden for this particular annotation.
     */
    public String overrideTarget() default "";

    /**
     * Omit implementations of this TypeRole.
     * This flag allows you to skip any implementations of the flagged TypeRole.
     * It is only effective on abstract types.
     * @return the rationale for omitting the check for implementing/overriding classes from the completeness check
     */
    public String omitImplementation() default "";
}
